package com.example.demo.thread;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * @author Code Farmer
 * @date 2020/5/22 15:10
 */
public class ThreadDemo3 {

    //总访问量
    //此处加volatile修改，保证可见性
    private volatile static int count = 0;

    //模拟访问的方法
    public static void request() throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(5);//模拟耗时5s
//        count++;
        int expectCount;
        //a.获取锁
        //b.获取以下count最新的值，记做LV
        while (!compareAndSwap((expectCount = getCount()), expectCount + 1)) {

        }
    }

    /**
     * @param expectCount count期望值
     * @param newCount    需要给count赋予的新值
     * @return 交换成功返回true；反之返回false
     */
    public static synchronized boolean compareAndSwap(int expectCount, int newCount) {
//        c.判断LV是否等于A，如果相等，则把B的值赋值给count，并返回true；否则返回false
//        d.释放锁
        if (expectCount == getCount()) {
            count = newCount;
            return true;
        }
        return false;
    }

    private static int getCount() {
        return count;
    }

    public static void main(String[] args) throws InterruptedException {
        long startTime = System.currentTimeMillis();
        int threadSize = 100;
        CountDownLatch countDownLatch = new CountDownLatch(threadSize);
        for (int i = 0; i < 100; i++) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    //模拟用户行为，每个用户访问10次网站
                    try {
                        for (int j = 0; j < 10; j++) {
                            request();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        countDownLatch.countDown();
                    }
                }
            });
            thread.start();
        }


        countDownLatch.await();
        long endTime = System.currentTimeMillis();
        System.out.println("访问用时：" + (endTime - startTime) + "ms");
        System.out.println(count);
    }

}
